// stringtype.h 的实现文件

#include "stringtype.h"

#include <stdlib.h>
#include <stdio.h>

#include "stringutils.h"

void string_new_fromchar(String* obj, Char* c) {
    obj->length = getStringLength(c);

    obj->c = (Char*) malloc(obj->length + 1);

    for (Int i = 0; i < obj->length; i++) {
        obj->c[i] = c[i];
    }

    obj->closed = false;
}

void string_new_fromchar_limit(String* obj, Char* c, Int limit) {
    obj->c = (Char*) malloc(limit + 1);
    for (Int i = 0; i < limit; i++) {
        obj->c[i] = c[i];
    }
    obj->closed = false;
    obj->length = limit;
}

void string_new_fromlength(String* obj, Int length) {
    obj->c = (Char*) malloc(length + 1);
    obj->closed = false;
    obj->length = length;
}

void string_new_frominterval(String* obj, Interval* interval) {
    obj->length = interval->end - interval->start;
    obj->c = (Char*) malloc(obj->length + 1);
    obj->closed = false;
}

void string_print(String* obj) {
    for (Int i = 0; i < obj->length; i++) {
        printf("%c", obj->c[i]);
    }
}

void string_print_raw(String* obj) {
    printf("%s", obj->c);
}

void string_println(String* obj) {
    string_print(obj);
    printf("\n");
}

void string_println_raw(String* obj) {
    string_print_raw(obj);
    printf("\n");
}

void string_append_char(String* obj, Char* c) {
    Char* temp;
    if (!obj->closed) {
        temp = malloc(obj->length);
        for (Int i = 0; i < obj->length; i++) {
            temp[i] = obj->c[i];
        }
        free(obj->c);
    }
    
    Int oldLength = obj->length;
    Int cLength = getStringLength(c);
    obj->length = obj->length + cLength;
    obj->c = malloc(obj->length + 1);
    for (Int i = 0; i < oldLength; i++) {
        obj->c[i] = temp[i];
    }
    for (Int i = 0; i < obj->length; i++) {
        obj->c[i + oldLength] = c[i];
    }
    if (obj->closed) {
        obj->closed = false;
    } else {
        free(temp);
    }
}

void string_append_char_limit(String* obj, Char* c, Int limit) {
    Char* temp;
    if (!obj->closed) {
        temp = malloc(obj->length);
        for (Int i = 0; i < obj->length; i++) {
            temp[i] = obj->c[i];
        }
        free(obj->c);
    }
    
    Int oldLength = obj->length;
    obj->length = obj->length + limit;
    obj->c = malloc(obj->length + 1);
    for (Int i = 0; i < oldLength; i++) {
        obj->c[i] = temp[i];
    }
    for (Int i = 0; i < obj->length; i++) {
        obj->c[i + oldLength] = c[i];
    }
    if (obj->closed) {
        obj->closed = false;
    } else {
        free(temp);
    }
}

void string_append_string(String* obj, String* ap) {
    if (ap->closed) return;
    Char* temp;
    if (!obj->closed) {
        temp = malloc(obj->length);
        for (Int i = 0; i < obj->length; i++) {
            temp[i] = obj->c[i];
        }
        free(obj->c);
    }
    
    Int oldLength = obj->length;
    obj->length = obj->length + ap->length;
    obj->c = malloc(obj->length + 1);
    for (Int i = 0; i < oldLength; i++) {
        obj->c[i] = temp[i];
    }
    for (Int i = 0; i < obj->length; i++) {
        obj->c[i + oldLength] = ap->c[i];
    }
    if (obj->closed) {
        obj->closed = false;
    } else {
        free(temp);
    }
}

Int string_length(String* obj) {
    return obj->length;
}

Byte string_isClosed(String* obj) {
    return obj->closed;
}
void string_close(String* obj) {
    obj->closed = true;
    obj->length = 0;
    free(obj->c);
    obj->c = null;
}